//
//  TalkViewController.m
//  ENTBoostChat
//
//  Created by zhong zf on 14-8-8.
//  Copyright (c) 2014年 EB. All rights reserved.
//

#import "TalkViewController.h"
#import "TalksTableViewController.h"
#import "MainViewController.h"
#import "ImageViewController.h"
#import "ENTBoost.h"
#import "BlockUtility.h"
#import "MJRefresh.h"
#import "UIImage+UIImageScale.h"

#define EB_CHAT_PER_PAGE_SIZE 10

@interface TalkViewController ()
{
    UIImage* _keyboardImage;
    UIImage* _emotionImage;
    BOOL _keyboardShow;
}
@end

@implementation TalkViewController

- (id)initWithCoder:(NSCoder *)aDecoder
{
    if(self = [super initWithCoder:aDecoder]) {
//        self.currentCallId = 0;
        self.depCode = 0;
        self.otherUid = 0;
        self.messages = [NSMutableArray array];
        _keyboardImage = [[UIImage imageNamed:@"keyboard"] scaleToSize:CGSizeMake(24, 24)];
        _emotionImage = [UIImage imageNamed:@"emotion"];
        _keyboardShow = NO;
        _isFirstShow = YES;
    }
    return self;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.talkTextView.delegate = self;
    self.talkTextView.editable = YES; //开启编辑模式
    self.talkTextView.font = [UIFont systemFontOfSize:18.0f]; //设定字体
    self.talkTextView.lineSpacing = 1.0f;
    self.talkTextView.paragraphSpacing = 0.0f;
    self.talkTextView.lineHeightMultiple = 0.0f;
    
    [self registerForKeyboardNotifications]; //注册键盘监控事件
    
    //读取本地聊天记录并显示
    NSArray* messages = [[ENTBoostKit sharedToolKit] messagesWithTalkId:self.talkId andBeginTime:nil endTime:nil perPageSize:EB_CHAT_PER_PAGE_SIZE currentPage:1 orderByTimeAscending:NO];
    [self addMessages:messages append:NO];
    //[self.messages addObjectsFromArray:[messages reverseObjectEnumerator].allObjects];
    
    //集成下拉刷新控件
    [self setupRefresh];
    
    //生成清空聊天记录的按钮
    UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:@"清空记录" style:UIBarButtonItemStylePlain target:self action:@selector(deleteMessages)];
    self.navigationItem.rightBarButtonItem = anotherButton;
    self.navigationItem.title = self.isGroup?self.depName:self.otherUserName;
    
    self.stampInputView = [[StampInputView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 216)];
    self.stampInputView.textView = self.talkTextView;
    [self.stampInputView fillStamps];

}

- (void)refreshStampInputView
{
    //刷新tableView，把原来缺失的图标显示出来
    [self.talkTableView reloadData];
    //填充表情图标
    [self.stampInputView fillStamps];
}

- (void)viewWillLayoutSubviews
{
    [self updateLayout];
}

//删除本Talk相关的全部聊天记录
- (void)deleteMessages
{
    UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"清空记录" message:@"真得要删除本对话全部聊天记录吗?" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
    [alertView show];
}

//定义的委托, 提示初始化失败后再次执行初始化
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1) {
        [[ENTBoostKit sharedToolKit] deleteMessagesWithTalkId:self.talkId];
        [self.messages removeAllObjects];
        [self.talkTableView reloadData];
    }
}

/**
 *  集成刷新控件
 */
- (void)setupRefresh
{
    // 1.下拉刷新(进入刷新状态就会调用self的headerRereshing)
    [self.talkTableView addHeaderWithTarget:self action:@selector(headerRereshing)];
    
    // 设置文字
    self.talkTableView.headerPullToRefreshText = @"下拉加载更多聊天记录";
    self.talkTableView.headerReleaseToRefreshText = @"松开马上加载";
    self.talkTableView.headerRefreshingText = @"加载中,请稍后...";
    
}

//执行刷新动作
- (void)headerRereshing
{
    NSUInteger originCount = self.messages.count;
    
    // 查询数据
    NSArray* messages;
    if(self.messages.count) {
        EBMessage* message = [self.messages objectAtIndex:0];
        messages = [[ENTBoostKit sharedToolKit] messagesFromLastMessageId:message.msgId orderByTimeAscending:NO perPageSize:EB_CHAT_PER_PAGE_SIZE];
    } else {
        messages = [[ENTBoostKit sharedToolKit] messagesWithTalkId:self.talkId andBeginTime:nil endTime:nil perPageSize:EB_CHAT_PER_PAGE_SIZE currentPage:1 orderByTimeAscending:NO];
    }
    // 加入到聊天界面中
    if (messages && messages.count) {
        [self addMessages:messages append:NO];
    }
    
    //滚动到未刷新前的记录位置
    NSUInteger scrollToRow = self.messages.count - originCount;
    if (scrollToRow) {
        NSIndexPath* indexPath = [NSIndexPath indexPathForRow:scrollToRow inSection:0];
        [self.talkTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
    }
    
    //调用endRefreshing可以结束刷新状态
    [self.talkTableView headerEndRefreshing];
}


- (void)viewDidAppear:(BOOL)animated
{
    //只有在第一次显示界面的时候才需要自动滚动到最后
    if(self.isFirstShow) {
        self.isFirstShow = NO;
        [self scrollToBottom:YES];
    }
}

- (void)viewWillDisappear:(BOOL)animated
{
    //设置聊天记录已读状态
    [[ENTBoostKit sharedToolKit] markMessagesAsReadedWithTBTalkId:self.talkId];
    [self.talksController updateBadgeWithTalkId:self.talkId];
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self]; //删除事件监测注册
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (BOOL)isGroup
{
    return self.depCode?YES:NO;
}

//点击发送按钮事件处理
- (IBAction)sendTextFieldTaped:(id)sender
{
    //    [self.talkTextField resignFirstResponder]; //隐藏键盘
    
    self.sendButton.enabled = NO; //禁止"发送"按钮
    
    BOOL waittingResult = NO, result = NO;
    [self detectAndLaunchCallWithWaitting:&waittingResult result:&result]; //检测会话
    
    if(result) {//会话就绪
        [self excuteSendMessage];
    } else if(waittingResult) { //等待呼叫结果
        NSString* talkId = self.talkId;
        __weak typeof(self) safeSelf = self;
        
        [BlockUtility performBlockInGlobalQueue:^{ //在非主线程中执行
            int maxTimes = 30; //最大重试次数
            __block int tryTimes = 0; //当前重试次数
            __block BOOL callReady = NO;
            ENTBoostKit* ebKit = [ENTBoostKit sharedToolKit];
            
            do {
                [NSThread sleepForTimeInterval:0.5]; //等待0.5秒
                EBTalk* talk = [ebKit talkWithTalkId:talkId];
                NSLog(@"check for talkId = %@, talk = %@, tryTimes = %i", talkId, talk, tryTimes+1);
                
                //会话准备就绪
                if(talk.isReady)
                    callReady = YES;
                
                tryTimes++;
            } while(!callReady && tryTimes < maxTimes);
            
            if(callReady) //会话就绪后
                [safeSelf excuteSendMessage];
            else //建立会话失败
                [safeSelf sendTextFailure:EBERR(EB_STATE_ERROR, @"建立会话失败")];
        }];
    }
}

- (void)sendTextFailure:(NSError*)error
{
    [BlockUtility performBlockInMainQueue:^{ //主线程中执行
        //提示发送失败
        NSString* msg = [NSString stringWithFormat:@"发送失败, code = %i, msg = %@", error.code, error.localizedDescription];
        UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:nil message:msg delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
        [alertView show];
        self.sendButton.enabled = YES; //启用"发送"按钮
    }];
}

- (void)detectAndLaunchCallWithWaitting:(BOOL*)waittingResult result:(BOOL*)result
{
    //初始化结果
    *waittingResult = NO;
    *result = NO;
    
    ENTBoostKit* ebKit = [ENTBoostKit sharedToolKit];
    
    //如果已经存在会话编号，则认为会话存在
    //    if(self.currentCallId) {
    //        *result = YES;
    //        return;
    //    }
    //TBTalk* tbTalk = [ebKit tbTalkWithTalkId:self.talkId];

    
    EBCallInfo* callInfo = [ebKit callInfoWithAccount:self.otherAccount depCode:self.depCode]; //查询是否已经有关联的会话
    if(!callInfo) {
        if(self.depCode) { //群组会话
            [ebKit callGroupWithDepCode:self.depCode onFailure:^(NSError *error) {
                NSLog(@"呼叫群组失败, depCode = %llu, code = %i, msg = %@", self.depCode, error.code, error.localizedDescription);
                [self sendTextFailure:error];
            }];
        } else { //一对一会话
            [ebKit callUserWithAccount:self.otherAccount onFailure:^(NSError *error) {
                NSLog(@"呼叫个人失败, account = %@, code = %li, msg = %@", self.otherAccount, (long)error.code, error.localizedDescription);
                [self sendTextFailure:error];
            }];
        }
        *waittingResult = YES;
    } else { //会话已经存在
        //self.currentCallId = callInfo.callId;
        *result = YES;
    }
}

//调用SDK执行发送信息任务
- (void)excuteSendMessage
{
    __weak typeof(self) safeSelf = self;
    [BlockUtility performBlockInMainQueue:^{
        ENTBoostKit* ebKit = [ENTBoostKit sharedToolKit];
        
//        //发送信息
//        NSString* text = [safeSelf.talkTextView.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
        
        //获取包含CTRunDelegate属性的分段
        NSAttributedString* attrText = self.talkTextView.attributedText;
        NSLog(@"attrText.length = %i", attrText.length);
        
        //信息内容只有空白字符，提示不允许发送空白内容
        NSString* text = attrText.string;
        if(text.length == 0) {
            UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:nil message:@"请输入内容" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
            [alertView show];
            
            safeSelf.sendButton.enabled = YES; //启用"发送"按钮
            return;
        }
        
        //检测并转换非字符内容(例如表情图标)
        NSMutableArray* attachRanges = [NSMutableArray array];
        NSMutableDictionary* emotions = [NSMutableDictionary dictionary];
        //获取包含CTRunDelegate属性的分段
        [attrText enumerateAttribute:(id)kCTRunDelegateAttributeName inRange:NSMakeRange(0, attrText.length) options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(id value, NSRange range, BOOL *stop) {
            CTRunDelegateRef runDelegate = (__bridge CTRunDelegateRef)value;
            SETextAttachment *attachment = (__bridge SETextAttachment *)CTRunDelegateGetRefCon(runDelegate);
            if(attachment) {
                //转换并暂存
                NSString* rangeStr = NSStringFromRange(range);
                [attachRanges addObject:rangeStr];
                EBEmotion* emotion = attachment.customData[STAMP_CUSTOM_DATA_EMOTION_NAME];
                emotions[rangeStr] = emotion;
                NSLog(@"data:%@, range:%@",emotion.resourceString , rangeStr);
            }
        }];
        
        //排序
        [attachRanges sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
            NSRange range1 = NSRangeFromString(obj1);
            NSRange range2 = NSRangeFromString(obj2);
            
            NSUInteger maxRange1 = NSMaxRange(range1);
            NSUInteger maxRange2 = NSMaxRange(range2);
            
            if (maxRange1 > maxRange2)
                return NSOrderedDescending;
            if (maxRange1 < maxRange2)
                return NSOrderedAscending;
            return NSOrderedSame;
        }];
        
        //获取对话归类
        EBTalk* talk = [ebKit talkWithTalkId:safeSelf.talkId];
        
        //生成信息实例
        EBMessage* message = [[EBMessage alloc] initWithFromUid:ebKit.accountInfo.uid callId:talk.currentCallId];
        
        //一般字符内容与非字符内容合并
        NSUInteger currentIndex = 0;
        if (attachRanges.count) { //有非字符内容(例如表情图标)
            for (int i=0; i < attachRanges.count; i++) {
                NSString* rangeStr = [attachRanges objectAtIndex:i];
                NSRange range = NSRangeFromString(rangeStr);
                
                //前面还有文本内容未加入消息
                if (range.location > currentIndex) {
                    NSString* tmpText = [text substringWithRange:NSMakeRange(currentIndex, range.location - currentIndex)];
                    EBChatText* chatText = [[EBChatText alloc] initWithText:tmpText];
                    [message addChatDot:chatText];
                }
                
                //表情资源加入消息
                EBEmotion* emotion = emotions[rangeStr];
                EBChatResource* chatResource = [[EBChatResource alloc] initWithResource:emotion.resId];
                [message addChatDot:chatResource];
                
                currentIndex = NSMaxRange(range);
            }
        }

        //遍历未完成,把剩余的字符内容加入到消息
        if (currentIndex < text.length) {
            EBChatText* chatText = [[EBChatText alloc] initWithText:[text substringWithRange:NSMakeRange(currentIndex, text.length - currentIndex)]];
            [message addChatDot:chatText];
        }

        //执行发送信息
        [ebKit sendMessage:message forCallId:talk.currentCallId onBegin:^(uint64_t msgId) {
            
            } onCompletion:^(uint64_t msgId){
                [BlockUtility performBlockInMainQueue:^{ //主线程中执行
                    //在聊天界面中显示本信息
                    [safeSelf addMessages:@[message] append:YES];
                    [safeSelf scrollToBottom:NO];
                    
                    //safeSelf.talkTextField.text = @""; //清空发送内容
                    [safeSelf.talkTextView clearAll]; //清空发送内容
                    safeSelf.sendButton.enabled = YES; //启用"发送"按钮
                    
                    //使上层的talks表视图更新排序
                    MainViewController* mainViewController = (MainViewController*)safeSelf.parentViewController.parentViewController;
                    [mainViewController.talksController adjustTableViewWithTalkId:safeSelf.talkId];
                }];
            } onFailure:^(NSError *error) {
                NSLog(@"发送信息失败, code = %i, msg = %@", error.code, error.localizedDescription);
                [safeSelf sendTextFailure:error];
            }];
    }];
}

- (BOOL)addMessages:(NSArray*)messages append:(BOOL)append
{
    NSUInteger originCount = self.messages.count;
    
    [self.talkTableView beginUpdates];
    
    //检查是否有重复消息(messageId相同)
    __weak typeof(self) safeSelf = self;
    [messages enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {@autoreleasepool {
        EBMessage* message = obj;
        
        __block BOOL isEqual = NO;
        [safeSelf.messages enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id innerObj, NSUInteger innerIdx, BOOL *innerStop) {
            EBMessage* innerMessage = innerObj;
            NSLog(@"addMessages message.msgId = %llu, innerMessage.msgId = %llu", message.msgId, innerMessage.msgId);
            if (message.msgId == innerMessage.msgId) {
                isEqual = YES;
                *innerStop = YES;
            }
        }];
        
        //找不到相同消息才加入到待显示的队列中
        if(!isEqual) {
            if(append)
                [safeSelf.messages addObject:obj];
            else
                [safeSelf.messages insertObject:obj atIndex:0];
        }
    }}];
    
    //生成索引路径
    NSMutableArray *insertIndexPaths = [NSMutableArray arrayWithCapacity:0];
    
    if(append) {
        for (int ind = originCount; ind < self.messages.count; ind++) {
            NSIndexPath *newPath =  [NSIndexPath indexPathForRow:ind inSection:0];
            [insertIndexPaths addObject:newPath];
        }
    } else {
        for (int ind = 0; ind < self.messages.count - originCount; ind++) {
            NSIndexPath *newPath =  [NSIndexPath indexPathForRow:ind inSection:0];
            [insertIndexPaths addObject:newPath];
        }
    }
    
    //插入到表视图
    if(insertIndexPaths.count > 0)
        [self.talkTableView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationFade];
    
    [self.talkTableView endUpdates];
    
    return originCount!=self.messages.count;
}

-(void)scrollToBottom:(BOOL)animated
{
    NSUInteger sectionCount = [self.talkTableView numberOfSections];
    if (sectionCount) {
        NSUInteger rowCount = [self.talkTableView numberOfRowsInSection:0];
        if (rowCount) {
            NSUInteger ii[2] = {0, rowCount - 1};
            NSIndexPath* indexPath = [NSIndexPath indexPathWithIndexes:ii length:2];
            [self.talkTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:animated];
        }
    }
}

#pragma mark - Keyboard
- (void)registerForKeyboardNotifications
{
    //设置键盘活动事件监测
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHidden:) name:UIKeyboardWillHideNotification object:nil];
//    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
}

//寻找主视图与底部toolbar相关的约束[间隔距离]
- (NSLayoutConstraint*)constraintForToolbar
{
    __weak typeof (self) safeSelf = self;
    UIToolbar* toolbar = (UIToolbar*)[self.view viewWithTag:110];
    
    NSArray* arry = [toolbar constraintsAffectingLayoutForAxis:UILayoutConstraintAxisVertical];
    
    __block NSLayoutConstraint* constraint;
    [arry enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        NSLayoutConstraint* tmpConstraint = obj;
//        NSLog(@"first item = %@(attr:%i)%@,  second item = %@(attr:%i)%@", ((NSObject*)tmpConstraint.firstItem).class, tmpConstraint.firstAttribute, tmpConstraint.firstItem, ((NSObject*)tmpConstraint.secondItem).class, tmpConstraint.secondAttribute, tmpConstraint.secondItem);
        
        if(tmpConstraint.firstItem == safeSelf.view && tmpConstraint.secondItem == toolbar && tmpConstraint.firstAttribute == NSLayoutAttributeBottom && tmpConstraint.secondAttribute == NSLayoutAttributeBottom) {
            //NSLog(@"found the toolbar's constraint");
            constraint = tmpConstraint;
            *stop = true;
        }
    }];
    
    return constraint;
}

//键盘显示事件
- (void)keyboardWasShown:(NSNotification *)notif
{
//    NSLog(@"keyboardWasShown-> NSConcreteNotification name:%@", notif.name);
    NSDictionary *info = [notif userInfo];
    CGRect keyboardBounds;
    [[info valueForKey:UIKeyboardFrameEndUserInfoKey] getValue: &keyboardBounds];
//    NSNumber *duration = [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];
//    NSNumber *curve = [info objectForKey:UIKeyboardAnimationCurveUserInfoKey];

    NSLayoutConstraint* constraint = [self constraintForToolbar];
    //toolbar往上升
    if(constraint) {
        constraint.constant = keyboardBounds.size.height;
        //[self.view updateConstraintsIfNeeded];
    } else {
        NSLog(@"error, not found the toolbar's constraint!!!");
    }
    
    //表视图往上移动一个键盘的高度
    if (!_keyboardShow) {
        CGPoint offset = self.talkTableView.contentOffset;
        [self.talkTableView setContentOffset:CGPointMake(0, offset.y + keyboardBounds.size.height) animated:NO];
    }
    _keyboardShow = YES;
}

//键盘即将隐藏事件
- (void)keyboardWillHidden:(NSNotification *)notif
{
//    NSLog(@"keyboardWillHidden-> NSConcreteNotification name:%@", notif.name);
    NSDictionary *info = [notif userInfo];
    CGRect keyboardBounds;
    [[info valueForKey:UIKeyboardFrameEndUserInfoKey] getValue: &keyboardBounds];
//    NSNumber *duration = [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];
//    NSNumber *curve = [info objectForKey:UIKeyboardAnimationCurveUserInfoKey];
    
    NSLayoutConstraint* constraint = [self constraintForToolbar];
    //toolbar往下降
    if(constraint) {
        constraint.constant = 0;
    } else {
        NSLog(@"error, not found the toolbar's constraint!!!");
    }
    
    //表视图往下移动一个键盘的高度
    if(_keyboardShow) {
        CGPoint offset = self.talkTableView.contentOffset;
        [self.talkTableView setContentOffset:CGPointMake(0, offset.y - keyboardBounds.size.height) animated:NO];
    }
    _keyboardShow =NO;
}

#pragma mark - UIScrollViewDelegate
static NSString *LCellIdentifier = @"chatCellL"; //左边头像样式的Cell
static NSString *RCellIdentifier = @"chatCellR"; //右边头像样式的Cell

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if([self.talkTextView isFirstResponder])
        [self.talkTextView resignFirstResponder];
}

#pragma mark - UITableViewDataSource
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//    NSLog(@"indexPath row = %i", indexPath.row);
    EBMessage* message = [self.messages objectAtIndex:indexPath.row];
    
    uint64_t myUid = [ENTBoostKit sharedToolKit].accountInfo.uid;
    BOOL fromSelf = message.fromUid==myUid?YES:NO;
    
    ChatCell* cell = [tableView dequeueReusableCellWithIdentifier:fromSelf?RCellIdentifier:LCellIdentifier];
    
    [cell setContent:message fromSelf:fromSelf];
    cell.delegate = self;

    return cell;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.messages.count;
}

#pragma mark - UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    EBMessage* message = [self.messages objectAtIndex:indexPath.row];

    static ChatCell* leftCell;
    static ChatCell* rightCell;
    static dispatch_once_t pred = 0;
    dispatch_once(&pred, ^{
        leftCell = [tableView dequeueReusableCellWithIdentifier:LCellIdentifier];
        rightCell = [tableView dequeueReusableCellWithIdentifier:RCellIdentifier];
    });
    
//    NSLog(@"height ======= %i start", indexPath.row);
    //判断信息是否由自己发出
    uint64_t myUid = [ENTBoostKit sharedToolKit].accountInfo.uid;
    BOOL fromSelf = message.fromUid==myUid?YES:NO;
    
    ChatCell* cell = fromSelf?rightCell:leftCell;
    [cell setContent:message fromSelf:fromSelf];

//    [cell setNeedsUpdateConstraints];
//    [cell updateConstraints];
//    ChatCell* cell = [tableView dequeueReusableCellWithIdentifier:@"chatCellR"];
    
//    [cell.contentView setNeedsLayout];
//    [cell.contentView layoutIfNeeded];
    
    CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    
//    NSLog(@"cell size %@, msgId = %llu", NSStringFromCGSize(size), message.msgId);
    
//    NSLog(@"height ======= %i end", indexPath.row);
    return size.height;
}

- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
    return NO;
}

#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
    [segue.destinationViewController setHidesBottomBarWhenPushed:YES];
}


#pragma mark - SECoreTextView

//- (void)textViewDidBeginEditing:(SETextView *)textView
//{
//    self.doneButton.enabled = YES;
//}
//
//- (void)textViewDidEndEditing:(SETextView *)textView
//{
//    self.doneButton.enabled = NO;
//}

//- (void)textViewDidChangeSelection:(SETextView *)textView
//{
//    NSRange selectedRange = textView.selectedRange;
//    if (selectedRange.location != NSNotFound && selectedRange.length > 0) {
//        self.inputAccessoryView.boldButton.enabled = YES;
//        self.inputAccessoryView.nomalButton.enabled = YES;
//    } else {
//        self.inputAccessoryView.boldButton.enabled = NO;
//        self.inputAccessoryView.nomalButton.enabled = NO;
//    }
//}

//显示图标表情按钮事件处理
- (IBAction)showStampInputView:(id)sender
{
    UIButton* button = (UIButton*)[self.view viewWithTag:111];
    
    if (!self.talkTextView.inputView) { //未显示表情图标视图
        self.talkTextView.inputView = self.stampInputView;
        [button setImage:_keyboardImage forState:UIControlStateNormal];
        
//        [UIView beginAnimations:@"show stamp view" context:nil];
//        [UIView setAnimationDuration:0.3];
//        [UIView setAnimationDelegate:self];
//        [UIView  setAnimationCurve: UIViewAnimationCurveEaseInOut];
        
        CGRect frame = self.stampInputView.frame;
        frame.origin.y = frame.size.height;
        self.stampInputView.frame = frame;
        [self.talkTextView reloadInputViews];
        
//        //提交UIView动画
//        [UIView commitAnimations];
        
    } else { //当前已显示表情图标视图
        self.talkTextView.inputView = nil;
        [button setImage:_emotionImage forState:UIControlStateNormal];
        
        [self.talkTextView reloadInputViews];
    }
    
    //        self.inputAccessoryView.keyboardButton.enabled = YES;
    //        self.inputAccessoryView.stampButton.enabled = NO;
    //    NSLog(@"stampInputView %@", NSStringFromRect(self.stampInputView.bounds));
}

- (void)textViewDidChange:(SETextView *)textView
{
    [self updateLayout];
}

- (void)updateLayout
{
    //计算内容变更后的显示大小
    CGSize containerSize = self.talkScrollView.frame.size;
    CGSize contentSize = [self.talkTextView sizeThatFits:containerSize];
    CGRect frame = self.talkTextView.frame;
    frame.size.height = MAX(contentSize.height, containerSize.height);
    
    //更新滚动视图的内容显示大小
    self.talkScrollView.contentSize = frame.size;
    
    //通过更新约束的方式设置textView高度
    //self.talkTextView.frame = frame;
    NSArray* arry = [self.talkTextView constraintsAffectingLayoutForAxis:UILayoutConstraintAxisVertical];
    for (NSLayoutConstraint* constraint in arry) {
        if(constraint.firstItem == self.talkTextView && constraint.secondItem == nil && constraint.firstAttribute == NSLayoutAttributeHeight) {
            constraint.constant = frame.size.height;
            break;
        }
    }
    
//    NSLog(@"tv:%@, sv:%@, cv:%@", NSStringFromSize(self.talkTextView.frame.size),  NSStringFromSize(self.talkScrollView.frame.size), NSStringFromSize(self.talkScrollView.contentSize));
    //滚动至输入光标处
    [self.talkScrollView scrollRectToVisible:self.talkTextView.caretRect animated:YES];
}

#pragma mark - imagePicker
//显示图片选择界面
- (IBAction)showImagePicker:(id)sender
{
    //    [self.talkTextView resignFirstResponder];
    
    UIImagePickerController *controller = [[UIImagePickerController alloc] init];
    controller.delegate = self;
    controller.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    controller.mediaTypes = @[(NSString*)kUTTypeImage];
    controller.allowsEditing = YES;
    
    [self presentViewController:controller animated:YES completion:NULL];
}

//选择图片完成回调
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    UIImage *image = info[UIImagePickerControllerEditedImage];
    if(!image)
        image = info[UIImagePickerControllerOriginalImage];
    
    [self dismissViewControllerAnimated:YES completion:NULL];
    
    //图片对象转换为二进制数据对象
    NSData *data = UIImagePNGRepresentation(image);
    if (!data) {
        data = UIImageJPEGRepresentation(image, 1.0);
    }
    
    if(!data) {
        NSLog(@"选中的图片读取异常");
        return;
    }
    
    //判断图片是否超过最大限制
    if (data.length>1024*1024*5) {
        UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"图片错误" message:@"图片太大了，不能超过5MB" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
        [alertView show];
        return;
    }
    
    [self sendImageData:data];
}

//发送富文本图片
- (void)sendImageData:(NSData*)data
{
    ENTBoostKit* ebKit = [ENTBoostKit sharedToolKit];
    __weak typeof(self) safeSelf = self;
    
    //获取对话归类
    EBTalk* talk = [ebKit talkWithTalkId:safeSelf.talkId];
    
    //生成信息实例
    EBMessage* message = [[EBMessage alloc] initWithFromUid:ebKit.accountInfo.uid callId:talk.currentCallId];
    EBChatImage* chatImage = [[EBChatImage alloc] initWithData:data];
    [message addChatDot:chatImage];
    
    //定义"发送内容显示在消息界面"的处理block
    void(^messageToInterface)(void) = ^{
        //在聊天界面中显示本信息
        [safeSelf addMessages:@[message] append:YES];
        [safeSelf scrollToBottom:NO];
        
        //使上层的talks表视图更新排序
        MainViewController* mainViewController = (MainViewController*)safeSelf.parentViewController.parentViewController;
        [mainViewController.talksController adjustTableViewWithTalkId:safeSelf.talkId];
    };
    
    //定义"发送图片失败"的处理block
    void(^sendPictureFailure)(void) = ^{
        //提示发送失败
        UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:nil message:@"发送图片失败" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
        [alertView show];
    };
    
    //检测会话状态
    BOOL waittingResult = NO, result = NO;
    [self detectAndLaunchCallWithWaitting:&waittingResult result:&result];
    if(result) { //会话就绪
        //执行发送信息
        [ebKit sendMessage:message forCallId:talk.currentCallId onBegin:^(uint64_t msgId) {
            message.msgId = msgId;
            [BlockUtility performBlockInMainQueue:messageToInterface];
        } onCompletion:^(uint64_t msgId){
            
        } onFailure:^(NSError *error) {
            NSLog(@"发送信息失败, code = %i, msg = %@", error.code, error.localizedDescription);
            [BlockUtility performBlockInMainQueue:sendPictureFailure]; //主线程中执行
        }];
    } else if(waittingResult) { //等待呼叫结果
        [BlockUtility performBlockInGlobalQueue:^{
            //等待会话就绪
            int maxTimes = 10; //最大重试次数
            __block int tryTimes = 0; //当前重试次数
            __block BOOL callReady = NO;
            do {
                [NSThread sleepForTimeInterval:0.5]; //等待0.5秒
                [BlockUtility performBlockInMainQueue:^{ //主线程中执行
                    //                    EBTalk* talk = [ebKit talkWithTalkId:safeSelf.talkId];
                    if(talk.isReady) { //会话准备就绪
                        callReady = YES;
                    }
                }];
                tryTimes++;
            } while(!callReady && tryTimes < maxTimes);
            
            if(callReady) { //会话就绪后
                [BlockUtility performBlockInMainQueue:messageToInterface];
                
                //执行发送信息
                [ebKit sendMessage:message forCallId:talk.currentCallId onBegin:^(uint64_t msgId) {
                    message.msgId = msgId;
                    [BlockUtility performBlockInMainQueue:messageToInterface];
                } onCompletion:^(uint64_t msgId){
                    
                } onFailure:^(NSError *error) {
                    NSLog(@"发送信息失败, code = %i, msg = %@", error.code, error.localizedDescription);
                    [BlockUtility performBlockInMainQueue:sendPictureFailure]; //主线程中执行
                }];
            } else { //建立会话失败
                [BlockUtility performBlockInMainQueue:sendPictureFailure]; //主线程中执行
            }
        }];
    }
}


#pragma mark - ChatCellDelegate
- (void)imageClick:(UIImage *)image
{
    ImageViewController* ivc =[[UIStoryboard storyboardWithName:@"ImageView" bundle:nil] instantiateViewControllerWithIdentifier:@"imageViewController_ID"];
    ivc.image = image;
    [self presentViewController:ivc animated:YES completion:nil];
}

@end
